﻿/*
 * Created by SharpDevelop.
 * User: wlm
 * Date: 2011-8-30
 * Time: 19:30
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace NCS_CS
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class testSortForm : Form
	{
		       public testSortForm()
        {
            InitializeComponent();
 
            // create list of data
            var _List = new System.Collections.Generic.List<Data> 
                { new Data(), new Data(), new Data(), new Data(), new Data() };
 
            // convert to sortable list
            var _Sortable = new SortableBindingList<Data>(_List);
 
            // create datagridview and bind
            var _DataGridView = new System.Windows.Forms.DataGridView
            {
                Dock = System.Windows.Forms.DockStyle.Fill,
                AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill,
                DataSource = _Sortable
            };
 
            // add grid to form
            this.Controls.Clear();
            this.Controls.Add(_DataGridView);
        }
 
        // sample data class
        public class Data
        {
            public Data()
            {
                Property1 = System.Guid.NewGuid().ToString();
                Property2 = System.Guid.NewGuid().ToString();
                Property3 = System.Guid.NewGuid().ToString();
            }
            public string Property1 { get; set; }
            public string Property2 { get; set; }
            public string Property3 { get; set; }
        }
 
        // generic sortable list 
        // ref: (http://www.tech.windowsapplication1.com/content/sortable-binding-list-custom-data-objects)
        public class SortableBindingList<T> : System.ComponentModel.BindingList<T>
        {
            // constructor
            public SortableBindingList(System.Collections.Generic.List<T> list)
                : base(list) { }
 
            // fields
            private bool m_IsSorted;
            private System.ComponentModel.ListSortDirection m_SortDirection;
            private System.ComponentModel.PropertyDescriptor m_SortProperty;
 
            // properties
            protected override System.ComponentModel.ListSortDirection SortDirectionCore { get { return m_SortDirection; } }
            protected override System.ComponentModel.PropertyDescriptor SortPropertyCore { get { return m_SortProperty; } }
            protected override bool IsSortedCore { get { return m_IsSorted; } }
            protected override bool SupportsSortingCore { get { return true; } }
 
            // methods
            protected override void RemoveSortCore() { m_IsSorted = false; }
            protected override void ApplySortCore(System.ComponentModel.PropertyDescriptor prop, System.ComponentModel.ListSortDirection direction)
            {
                if (prop.PropertyType.GetInterface("IComparable") == null)
                    return;
                var _List = this.Items as System.Collections.Generic.List<T>;
                if (_List == null)
                {
                    m_IsSorted = false;
                }
                else
                {
                    var _Comparer = new PropertyComparer(prop.Name, direction);
                    _List.Sort(_Comparer);
                    m_IsSorted = true;
                    m_SortDirection = direction;
                    m_SortProperty = prop;
                }
                OnListChanged(new System.ComponentModel.ListChangedEventArgs(System.ComponentModel.ListChangedType.Reset, -1));
            }
 
            // sub class
            public class PropertyComparer : System.Collections.Generic.IComparer<T>
            {
                // properties
                private System.Reflection.PropertyInfo PropInfo { get; set; }
                private System.ComponentModel.ListSortDirection Direction { get; set; }
 
                // methods
                public PropertyComparer(string propName, System.ComponentModel.ListSortDirection direction)
                {
                    this.PropInfo = typeof(T).GetProperty(propName);
                    this.Direction = direction;
                }
                public int Compare(T x, T y)
                {
                    var _X = PropInfo.GetValue(x, null);
                    var _Y = PropInfo.GetValue(y, null);
                    if (Direction == System.ComponentModel.ListSortDirection.Ascending)
                        return System.Collections.Comparer.Default.Compare(_X, _Y);
                    else
                        return System.Collections.Comparer.Default.Compare(_Y, _X);
                }
            }
        }

        private void testSortForm_Load(object sender, EventArgs e)
        {

        }
	}
}
